<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>如何利用webpack来优化前端性能？ | 房飞跃的博客</title>
    <meta name="generator" content="VuePress 1.8.2">
    <link rel="apple-touch-icon" href="/apple-touch-icon.png">
    <link rel="icon" href="/favicon.ico">
    <link rel="manifest" href="/manifest.json">
    <meta name="description" content="房飞跃的博客">
    <meta name="theme-color" content="#ffffff">
    
    <link rel="preload" href="/assets/css/0.styles.e57fdc06.css" as="style"><link rel="preload" href="/assets/js/app.8c5a7a92.js" as="script"><link rel="preload" href="/assets/js/2.8e30e130.js" as="script"><link rel="preload" href="/assets/js/325.f54af6ec.js" as="script"><link rel="preload" href="/assets/js/64.0323ed89.js" as="script"><link rel="prefetch" href="/assets/js/10.e695640a.js"><link rel="prefetch" href="/assets/js/100.fae9757f.js"><link rel="prefetch" href="/assets/js/101.d26f7a9a.js"><link rel="prefetch" href="/assets/js/102.e9b20f43.js"><link rel="prefetch" href="/assets/js/103.6d251ff3.js"><link rel="prefetch" href="/assets/js/104.5de918be.js"><link rel="prefetch" href="/assets/js/105.aead61a1.js"><link rel="prefetch" href="/assets/js/106.09a5decb.js"><link rel="prefetch" href="/assets/js/107.a44fc48a.js"><link rel="prefetch" href="/assets/js/108.cec63522.js"><link rel="prefetch" href="/assets/js/109.db1a4ed7.js"><link rel="prefetch" href="/assets/js/11.769ac82c.js"><link rel="prefetch" href="/assets/js/110.10914d38.js"><link rel="prefetch" href="/assets/js/111.2c0ddf25.js"><link rel="prefetch" href="/assets/js/112.c792ca07.js"><link rel="prefetch" href="/assets/js/113.a769ad8f.js"><link rel="prefetch" href="/assets/js/114.c1dca6a0.js"><link rel="prefetch" href="/assets/js/115.82e1fb4f.js"><link rel="prefetch" href="/assets/js/116.c927762b.js"><link rel="prefetch" href="/assets/js/117.5c14eedf.js"><link rel="prefetch" href="/assets/js/118.24861bb6.js"><link rel="prefetch" href="/assets/js/119.3fafaebf.js"><link rel="prefetch" href="/assets/js/12.23031504.js"><link rel="prefetch" href="/assets/js/120.a9ff8fae.js"><link rel="prefetch" href="/assets/js/121.3eb4b3a1.js"><link rel="prefetch" href="/assets/js/122.ff06cffe.js"><link rel="prefetch" href="/assets/js/123.aaf767a6.js"><link rel="prefetch" href="/assets/js/124.4daf257a.js"><link rel="prefetch" href="/assets/js/125.e7e71d3f.js"><link rel="prefetch" href="/assets/js/126.cdee6d86.js"><link rel="prefetch" href="/assets/js/127.aa133c3f.js"><link rel="prefetch" href="/assets/js/128.a8e7d8b2.js"><link rel="prefetch" href="/assets/js/129.dcca2d84.js"><link rel="prefetch" href="/assets/js/13.f37f647e.js"><link rel="prefetch" href="/assets/js/130.3925fb20.js"><link rel="prefetch" href="/assets/js/131.a3a759ed.js"><link rel="prefetch" href="/assets/js/132.84bb9bf9.js"><link rel="prefetch" href="/assets/js/133.30fceda7.js"><link rel="prefetch" href="/assets/js/134.e02f66bf.js"><link rel="prefetch" href="/assets/js/135.71a35d7f.js"><link rel="prefetch" href="/assets/js/136.77762773.js"><link rel="prefetch" href="/assets/js/137.b9741de3.js"><link rel="prefetch" href="/assets/js/138.59b64aa0.js"><link rel="prefetch" href="/assets/js/139.d81e68a1.js"><link rel="prefetch" href="/assets/js/14.0091824d.js"><link rel="prefetch" href="/assets/js/140.68388ddb.js"><link rel="prefetch" href="/assets/js/141.e69cc877.js"><link rel="prefetch" href="/assets/js/142.65fc1806.js"><link rel="prefetch" href="/assets/js/143.4f1e9b3d.js"><link rel="prefetch" href="/assets/js/144.5cf4bdda.js"><link rel="prefetch" href="/assets/js/145.1a1cdb18.js"><link rel="prefetch" href="/assets/js/146.ef4fe2c3.js"><link rel="prefetch" href="/assets/js/147.f5e5d206.js"><link rel="prefetch" href="/assets/js/148.07c7208f.js"><link rel="prefetch" href="/assets/js/149.fb71df8d.js"><link rel="prefetch" href="/assets/js/15.4e1991f3.js"><link rel="prefetch" href="/assets/js/150.771bcbfe.js"><link rel="prefetch" href="/assets/js/151.de02cd55.js"><link rel="prefetch" href="/assets/js/152.6a5b243d.js"><link rel="prefetch" href="/assets/js/153.c1c426d2.js"><link rel="prefetch" href="/assets/js/154.51e08a99.js"><link rel="prefetch" href="/assets/js/155.ab801c7a.js"><link rel="prefetch" href="/assets/js/156.e62111f0.js"><link rel="prefetch" href="/assets/js/157.67f19eb7.js"><link rel="prefetch" href="/assets/js/158.3e57553c.js"><link rel="prefetch" href="/assets/js/159.f01ea56a.js"><link rel="prefetch" href="/assets/js/16.aafe549d.js"><link rel="prefetch" href="/assets/js/160.81468500.js"><link rel="prefetch" href="/assets/js/161.8341c4c9.js"><link rel="prefetch" href="/assets/js/162.18cd1d1e.js"><link rel="prefetch" href="/assets/js/163.2ed65e27.js"><link rel="prefetch" href="/assets/js/164.1c0adbfd.js"><link rel="prefetch" href="/assets/js/165.4382f96e.js"><link rel="prefetch" href="/assets/js/166.47ad10ec.js"><link rel="prefetch" href="/assets/js/167.ee3e3de3.js"><link rel="prefetch" href="/assets/js/168.1273ebb0.js"><link rel="prefetch" href="/assets/js/169.bb6578e0.js"><link rel="prefetch" href="/assets/js/17.4548c40c.js"><link rel="prefetch" href="/assets/js/170.6aef0437.js"><link rel="prefetch" href="/assets/js/171.4818ad12.js"><link rel="prefetch" href="/assets/js/172.7f4674ed.js"><link rel="prefetch" href="/assets/js/173.25951cfa.js"><link rel="prefetch" href="/assets/js/174.604b8889.js"><link rel="prefetch" href="/assets/js/175.752d6221.js"><link rel="prefetch" href="/assets/js/176.ee6ccaf2.js"><link rel="prefetch" href="/assets/js/177.df3e7548.js"><link rel="prefetch" href="/assets/js/178.0c05bdea.js"><link rel="prefetch" href="/assets/js/179.fa300396.js"><link rel="prefetch" href="/assets/js/18.4a166581.js"><link rel="prefetch" href="/assets/js/180.78580e5a.js"><link rel="prefetch" href="/assets/js/181.c08c58e9.js"><link rel="prefetch" href="/assets/js/182.425fd44a.js"><link rel="prefetch" href="/assets/js/183.643e0376.js"><link rel="prefetch" href="/assets/js/184.28243fe4.js"><link rel="prefetch" href="/assets/js/185.145fafb0.js"><link rel="prefetch" href="/assets/js/186.9c005fb8.js"><link rel="prefetch" href="/assets/js/187.a1c8a8da.js"><link rel="prefetch" href="/assets/js/188.b78deff0.js"><link rel="prefetch" href="/assets/js/189.86432945.js"><link rel="prefetch" href="/assets/js/19.992da7e4.js"><link rel="prefetch" href="/assets/js/190.b6c616c9.js"><link rel="prefetch" href="/assets/js/191.d2a4a045.js"><link rel="prefetch" href="/assets/js/192.ce93c157.js"><link rel="prefetch" href="/assets/js/193.f45b56e8.js"><link rel="prefetch" href="/assets/js/194.60166b01.js"><link rel="prefetch" href="/assets/js/195.fea0fdcc.js"><link rel="prefetch" href="/assets/js/196.7f9353e4.js"><link rel="prefetch" href="/assets/js/197.2a8de731.js"><link rel="prefetch" href="/assets/js/198.6f3d807b.js"><link rel="prefetch" href="/assets/js/199.75028922.js"><link rel="prefetch" href="/assets/js/20.e27836ed.js"><link rel="prefetch" href="/assets/js/200.36fbe8e0.js"><link rel="prefetch" href="/assets/js/201.ca3a3d7d.js"><link rel="prefetch" href="/assets/js/202.8cc508cd.js"><link rel="prefetch" href="/assets/js/203.eb6662a4.js"><link rel="prefetch" href="/assets/js/204.a75edc0d.js"><link rel="prefetch" href="/assets/js/205.77cc7661.js"><link rel="prefetch" href="/assets/js/206.7cfc88ae.js"><link rel="prefetch" href="/assets/js/207.9d5b5377.js"><link rel="prefetch" href="/assets/js/208.9308a3b3.js"><link rel="prefetch" href="/assets/js/209.cbee10e7.js"><link rel="prefetch" href="/assets/js/21.9bc4424f.js"><link rel="prefetch" href="/assets/js/210.3dbd53b3.js"><link rel="prefetch" href="/assets/js/211.ffc0051e.js"><link rel="prefetch" href="/assets/js/212.420b9a23.js"><link rel="prefetch" href="/assets/js/213.da84f0aa.js"><link rel="prefetch" href="/assets/js/214.2a5308ff.js"><link rel="prefetch" href="/assets/js/215.bc87143e.js"><link rel="prefetch" href="/assets/js/216.f099b04d.js"><link rel="prefetch" href="/assets/js/217.39cc059e.js"><link rel="prefetch" href="/assets/js/218.3b588871.js"><link rel="prefetch" href="/assets/js/219.8c7c7f40.js"><link rel="prefetch" href="/assets/js/22.287b20ef.js"><link rel="prefetch" href="/assets/js/220.6a490188.js"><link rel="prefetch" href="/assets/js/221.a06fe7b9.js"><link rel="prefetch" href="/assets/js/222.0da34a82.js"><link rel="prefetch" href="/assets/js/223.6d6abad9.js"><link rel="prefetch" href="/assets/js/224.de157359.js"><link rel="prefetch" href="/assets/js/225.c733d3d1.js"><link rel="prefetch" href="/assets/js/226.039d453b.js"><link rel="prefetch" href="/assets/js/227.dbe84815.js"><link rel="prefetch" href="/assets/js/228.4850e3f3.js"><link rel="prefetch" href="/assets/js/229.322215a9.js"><link rel="prefetch" href="/assets/js/23.c1fc6d56.js"><link rel="prefetch" href="/assets/js/230.2469fb45.js"><link rel="prefetch" href="/assets/js/231.a77224ae.js"><link rel="prefetch" href="/assets/js/232.56534eb1.js"><link rel="prefetch" href="/assets/js/233.f69b682d.js"><link rel="prefetch" href="/assets/js/234.33fecaf9.js"><link rel="prefetch" href="/assets/js/235.3152a6d8.js"><link rel="prefetch" href="/assets/js/236.4a45a619.js"><link rel="prefetch" href="/assets/js/237.683796c5.js"><link rel="prefetch" href="/assets/js/238.4183baab.js"><link rel="prefetch" href="/assets/js/239.967342f3.js"><link rel="prefetch" href="/assets/js/24.c4266153.js"><link rel="prefetch" href="/assets/js/240.4ebdaa3e.js"><link rel="prefetch" href="/assets/js/241.3853f81e.js"><link rel="prefetch" href="/assets/js/242.0be00241.js"><link rel="prefetch" href="/assets/js/243.27a16565.js"><link rel="prefetch" href="/assets/js/244.4b6c0842.js"><link rel="prefetch" href="/assets/js/245.0ff5b09e.js"><link rel="prefetch" href="/assets/js/246.ec9708bc.js"><link rel="prefetch" href="/assets/js/247.33dd2e3f.js"><link rel="prefetch" href="/assets/js/248.e095c83d.js"><link rel="prefetch" href="/assets/js/249.e35dae0b.js"><link rel="prefetch" href="/assets/js/25.0bd19957.js"><link rel="prefetch" href="/assets/js/250.b7dda30b.js"><link rel="prefetch" href="/assets/js/251.373c219f.js"><link rel="prefetch" href="/assets/js/252.f02d8652.js"><link rel="prefetch" href="/assets/js/253.0129ab3b.js"><link rel="prefetch" href="/assets/js/254.05bc87ae.js"><link rel="prefetch" href="/assets/js/255.93959060.js"><link rel="prefetch" href="/assets/js/256.036268bb.js"><link rel="prefetch" href="/assets/js/257.4cfe4c46.js"><link rel="prefetch" href="/assets/js/258.70f49e1e.js"><link rel="prefetch" href="/assets/js/259.e92d7a7e.js"><link rel="prefetch" href="/assets/js/26.cd8cc5bc.js"><link rel="prefetch" href="/assets/js/260.24ecb139.js"><link rel="prefetch" href="/assets/js/261.32f0c433.js"><link rel="prefetch" href="/assets/js/262.aca4b5e9.js"><link rel="prefetch" href="/assets/js/263.0051554a.js"><link rel="prefetch" href="/assets/js/264.063d3092.js"><link rel="prefetch" href="/assets/js/265.de1fe60c.js"><link rel="prefetch" href="/assets/js/266.4407a594.js"><link rel="prefetch" href="/assets/js/267.9318dca9.js"><link rel="prefetch" href="/assets/js/268.b9696b4c.js"><link rel="prefetch" href="/assets/js/269.21743bc6.js"><link rel="prefetch" href="/assets/js/27.e0c9a2d1.js"><link rel="prefetch" href="/assets/js/270.64175904.js"><link rel="prefetch" href="/assets/js/271.ab988e51.js"><link rel="prefetch" href="/assets/js/272.40190656.js"><link rel="prefetch" href="/assets/js/273.124f97d6.js"><link rel="prefetch" href="/assets/js/274.ac2ae949.js"><link rel="prefetch" href="/assets/js/275.84112c31.js"><link rel="prefetch" href="/assets/js/276.5cd3a2f1.js"><link rel="prefetch" href="/assets/js/277.dfd266d2.js"><link rel="prefetch" href="/assets/js/278.2c22b507.js"><link rel="prefetch" href="/assets/js/279.143630b9.js"><link rel="prefetch" href="/assets/js/28.ee8b098b.js"><link rel="prefetch" href="/assets/js/280.e52e72d5.js"><link rel="prefetch" href="/assets/js/281.fa255716.js"><link rel="prefetch" href="/assets/js/282.33cf3680.js"><link rel="prefetch" href="/assets/js/283.8aaeb880.js"><link rel="prefetch" href="/assets/js/284.cce2c80c.js"><link rel="prefetch" href="/assets/js/285.649e1ab2.js"><link rel="prefetch" href="/assets/js/286.93d1a5fb.js"><link rel="prefetch" href="/assets/js/287.95ecc60d.js"><link rel="prefetch" href="/assets/js/288.d0316c60.js"><link rel="prefetch" href="/assets/js/289.96b0da90.js"><link rel="prefetch" href="/assets/js/29.f1800df7.js"><link rel="prefetch" href="/assets/js/290.a0ec1eb0.js"><link rel="prefetch" href="/assets/js/291.000c9293.js"><link rel="prefetch" href="/assets/js/292.aa442a45.js"><link rel="prefetch" href="/assets/js/293.ad41a62d.js"><link rel="prefetch" href="/assets/js/294.d01fa093.js"><link rel="prefetch" href="/assets/js/295.988cbaa2.js"><link rel="prefetch" href="/assets/js/296.b4376d7c.js"><link rel="prefetch" href="/assets/js/297.53d3839b.js"><link rel="prefetch" href="/assets/js/298.e41d3af5.js"><link rel="prefetch" href="/assets/js/299.7530e3f7.js"><link rel="prefetch" href="/assets/js/3.0318d431.js"><link rel="prefetch" href="/assets/js/30.e022632d.js"><link rel="prefetch" href="/assets/js/300.b89cf9f0.js"><link rel="prefetch" href="/assets/js/301.538c5d13.js"><link rel="prefetch" href="/assets/js/302.e61e98d4.js"><link rel="prefetch" href="/assets/js/303.e69fdf1f.js"><link rel="prefetch" href="/assets/js/304.12cf05d2.js"><link rel="prefetch" href="/assets/js/305.05630898.js"><link rel="prefetch" href="/assets/js/306.4423e4cb.js"><link rel="prefetch" href="/assets/js/307.ec499705.js"><link rel="prefetch" href="/assets/js/308.eae04a19.js"><link rel="prefetch" href="/assets/js/309.e8cdb29d.js"><link rel="prefetch" href="/assets/js/31.a2dfbc5f.js"><link rel="prefetch" href="/assets/js/310.3770a9fc.js"><link rel="prefetch" href="/assets/js/311.79ae7adb.js"><link rel="prefetch" href="/assets/js/312.fd3baefc.js"><link rel="prefetch" href="/assets/js/313.895f6dcd.js"><link rel="prefetch" href="/assets/js/314.85943d2f.js"><link rel="prefetch" href="/assets/js/315.69631810.js"><link rel="prefetch" href="/assets/js/316.b025621c.js"><link rel="prefetch" href="/assets/js/317.7b7974aa.js"><link rel="prefetch" href="/assets/js/318.972a129d.js"><link rel="prefetch" href="/assets/js/319.65a4d2cf.js"><link rel="prefetch" href="/assets/js/32.b143e718.js"><link rel="prefetch" href="/assets/js/320.e5635579.js"><link rel="prefetch" href="/assets/js/321.845573fa.js"><link rel="prefetch" href="/assets/js/322.0f95ad9a.js"><link rel="prefetch" href="/assets/js/323.f7d22184.js"><link rel="prefetch" href="/assets/js/324.eb027f24.js"><link rel="prefetch" href="/assets/js/326.7a921d9f.js"><link rel="prefetch" href="/assets/js/327.e9c43c17.js"><link rel="prefetch" href="/assets/js/328.586efc33.js"><link rel="prefetch" href="/assets/js/329.47017c3f.js"><link rel="prefetch" href="/assets/js/33.e17e09ac.js"><link rel="prefetch" href="/assets/js/330.81032fbd.js"><link rel="prefetch" href="/assets/js/331.ce9966db.js"><link rel="prefetch" href="/assets/js/332.c28e794e.js"><link rel="prefetch" href="/assets/js/333.4564d08a.js"><link rel="prefetch" href="/assets/js/334.3b421837.js"><link rel="prefetch" href="/assets/js/335.b2b74b9d.js"><link rel="prefetch" href="/assets/js/336.9dd1e510.js"><link rel="prefetch" href="/assets/js/337.03042431.js"><link rel="prefetch" href="/assets/js/338.1bc0b80f.js"><link rel="prefetch" href="/assets/js/339.e517fc5c.js"><link rel="prefetch" href="/assets/js/34.f287ac3d.js"><link rel="prefetch" href="/assets/js/340.f90d2df3.js"><link rel="prefetch" href="/assets/js/341.eccb4ec1.js"><link rel="prefetch" href="/assets/js/342.b3386439.js"><link rel="prefetch" href="/assets/js/343.2ee6901d.js"><link rel="prefetch" href="/assets/js/344.e6913fc7.js"><link rel="prefetch" href="/assets/js/345.a72760e7.js"><link rel="prefetch" href="/assets/js/346.13984d25.js"><link rel="prefetch" href="/assets/js/347.6b59cbaf.js"><link rel="prefetch" href="/assets/js/348.f43d5e47.js"><link rel="prefetch" href="/assets/js/349.fe8641cf.js"><link rel="prefetch" href="/assets/js/35.5a1dace7.js"><link rel="prefetch" href="/assets/js/350.0ceb9652.js"><link rel="prefetch" href="/assets/js/351.08e70696.js"><link rel="prefetch" href="/assets/js/352.958f535b.js"><link rel="prefetch" href="/assets/js/353.51463d78.js"><link rel="prefetch" href="/assets/js/354.6169e165.js"><link rel="prefetch" href="/assets/js/355.10447463.js"><link rel="prefetch" href="/assets/js/356.32983151.js"><link rel="prefetch" href="/assets/js/357.39e998b6.js"><link rel="prefetch" href="/assets/js/358.1f40aee7.js"><link rel="prefetch" href="/assets/js/359.d1e82e86.js"><link rel="prefetch" href="/assets/js/36.b6f4332a.js"><link rel="prefetch" href="/assets/js/360.9096bf48.js"><link rel="prefetch" href="/assets/js/361.e2c0815a.js"><link rel="prefetch" href="/assets/js/362.66983024.js"><link rel="prefetch" href="/assets/js/363.d7f0691d.js"><link rel="prefetch" href="/assets/js/364.d96ddc65.js"><link rel="prefetch" href="/assets/js/365.c92ad624.js"><link rel="prefetch" href="/assets/js/366.dfd66280.js"><link rel="prefetch" href="/assets/js/367.01503521.js"><link rel="prefetch" href="/assets/js/368.8d83b9c1.js"><link rel="prefetch" href="/assets/js/369.f8e08a4f.js"><link rel="prefetch" href="/assets/js/37.f1a16008.js"><link rel="prefetch" href="/assets/js/370.70b912f3.js"><link rel="prefetch" href="/assets/js/371.dcefb388.js"><link rel="prefetch" href="/assets/js/372.a81a499a.js"><link rel="prefetch" href="/assets/js/373.94458b0f.js"><link rel="prefetch" href="/assets/js/374.a406f06f.js"><link rel="prefetch" href="/assets/js/375.87287c02.js"><link rel="prefetch" href="/assets/js/376.26088425.js"><link rel="prefetch" href="/assets/js/377.b9ee096c.js"><link rel="prefetch" href="/assets/js/378.7a1b6fa7.js"><link rel="prefetch" href="/assets/js/379.3e2b62fc.js"><link rel="prefetch" href="/assets/js/38.59f5160c.js"><link rel="prefetch" href="/assets/js/380.d741385f.js"><link rel="prefetch" href="/assets/js/381.afc0104a.js"><link rel="prefetch" href="/assets/js/382.a8c02915.js"><link rel="prefetch" href="/assets/js/383.7fca9756.js"><link rel="prefetch" href="/assets/js/384.d08aa931.js"><link rel="prefetch" href="/assets/js/385.c3ab471f.js"><link rel="prefetch" href="/assets/js/386.7314b80e.js"><link rel="prefetch" href="/assets/js/387.8db3a14a.js"><link rel="prefetch" href="/assets/js/388.f618a3b3.js"><link rel="prefetch" href="/assets/js/389.4d35947d.js"><link rel="prefetch" href="/assets/js/39.3cf9af40.js"><link rel="prefetch" href="/assets/js/390.a8e04e41.js"><link rel="prefetch" href="/assets/js/391.a31e9a62.js"><link rel="prefetch" href="/assets/js/392.d9321e46.js"><link rel="prefetch" href="/assets/js/393.6c4834d0.js"><link rel="prefetch" href="/assets/js/394.fd0a0ea4.js"><link rel="prefetch" href="/assets/js/395.0f27ab48.js"><link rel="prefetch" href="/assets/js/396.70044e25.js"><link rel="prefetch" href="/assets/js/397.07b2c0a6.js"><link rel="prefetch" href="/assets/js/398.ba95a9c5.js"><link rel="prefetch" href="/assets/js/399.8b310fbc.js"><link rel="prefetch" href="/assets/js/4.45f61616.js"><link rel="prefetch" href="/assets/js/40.fcf089d7.js"><link rel="prefetch" href="/assets/js/400.7ff77c6c.js"><link rel="prefetch" href="/assets/js/401.840e0c7c.js"><link rel="prefetch" href="/assets/js/402.a722c16f.js"><link rel="prefetch" href="/assets/js/403.1a3c12fb.js"><link rel="prefetch" href="/assets/js/404.7da4d4a4.js"><link rel="prefetch" href="/assets/js/405.76a07310.js"><link rel="prefetch" href="/assets/js/406.176db1fd.js"><link rel="prefetch" href="/assets/js/407.ff3da33f.js"><link rel="prefetch" href="/assets/js/408.3b4dfb3a.js"><link rel="prefetch" href="/assets/js/409.05692a2e.js"><link rel="prefetch" href="/assets/js/41.3f0a746d.js"><link rel="prefetch" href="/assets/js/410.615dc40b.js"><link rel="prefetch" href="/assets/js/411.e542a59f.js"><link rel="prefetch" href="/assets/js/412.16fc0c97.js"><link rel="prefetch" href="/assets/js/413.b9f30c37.js"><link rel="prefetch" href="/assets/js/414.9629300e.js"><link rel="prefetch" href="/assets/js/415.5c12951e.js"><link rel="prefetch" href="/assets/js/416.3ede10bc.js"><link rel="prefetch" href="/assets/js/417.5bc08adb.js"><link rel="prefetch" href="/assets/js/418.0a54fe32.js"><link rel="prefetch" href="/assets/js/419.97ebd724.js"><link rel="prefetch" href="/assets/js/42.d0fdcdd4.js"><link rel="prefetch" href="/assets/js/420.d3f60a7a.js"><link rel="prefetch" href="/assets/js/421.6b187cc9.js"><link rel="prefetch" href="/assets/js/422.268b38aa.js"><link rel="prefetch" href="/assets/js/423.00f151fe.js"><link rel="prefetch" href="/assets/js/424.5d54e48d.js"><link rel="prefetch" href="/assets/js/425.b0e71df6.js"><link rel="prefetch" href="/assets/js/426.fb5d6c08.js"><link rel="prefetch" href="/assets/js/427.a7a42bdb.js"><link rel="prefetch" href="/assets/js/428.b41b80fb.js"><link rel="prefetch" href="/assets/js/429.aff3b223.js"><link rel="prefetch" href="/assets/js/43.7812871c.js"><link rel="prefetch" href="/assets/js/430.9bded6a2.js"><link rel="prefetch" href="/assets/js/431.fbd064dd.js"><link rel="prefetch" href="/assets/js/432.a0ccaf13.js"><link rel="prefetch" href="/assets/js/433.70729631.js"><link rel="prefetch" href="/assets/js/434.7ff21dc4.js"><link rel="prefetch" href="/assets/js/435.ba6f0c33.js"><link rel="prefetch" href="/assets/js/436.abcca44e.js"><link rel="prefetch" href="/assets/js/437.2b2333cb.js"><link rel="prefetch" href="/assets/js/438.93ea3d14.js"><link rel="prefetch" href="/assets/js/439.c1b946ea.js"><link rel="prefetch" href="/assets/js/44.d2bbbf62.js"><link rel="prefetch" href="/assets/js/440.a5c5071e.js"><link rel="prefetch" href="/assets/js/441.bad7a6f2.js"><link rel="prefetch" href="/assets/js/442.97a45e71.js"><link rel="prefetch" href="/assets/js/443.9dd7a744.js"><link rel="prefetch" href="/assets/js/444.b2e74ec9.js"><link rel="prefetch" href="/assets/js/445.181b11ad.js"><link rel="prefetch" href="/assets/js/446.1d43ea57.js"><link rel="prefetch" href="/assets/js/447.a75ca861.js"><link rel="prefetch" href="/assets/js/448.7e177e61.js"><link rel="prefetch" href="/assets/js/449.0e124a1f.js"><link rel="prefetch" href="/assets/js/45.2181b5c6.js"><link rel="prefetch" href="/assets/js/450.d18c5137.js"><link rel="prefetch" href="/assets/js/451.0296f837.js"><link rel="prefetch" href="/assets/js/452.1f5d56a5.js"><link rel="prefetch" href="/assets/js/453.6f67fa9b.js"><link rel="prefetch" href="/assets/js/454.d96cd4e8.js"><link rel="prefetch" href="/assets/js/455.488f2e23.js"><link rel="prefetch" href="/assets/js/456.264d0da2.js"><link rel="prefetch" href="/assets/js/457.329d4d26.js"><link rel="prefetch" href="/assets/js/458.d20d34f9.js"><link rel="prefetch" href="/assets/js/459.dd4fad09.js"><link rel="prefetch" href="/assets/js/46.d69710e9.js"><link rel="prefetch" href="/assets/js/460.e1f8580c.js"><link rel="prefetch" href="/assets/js/461.d47e1ab7.js"><link rel="prefetch" href="/assets/js/462.54b49f34.js"><link rel="prefetch" href="/assets/js/463.2d1bb289.js"><link rel="prefetch" href="/assets/js/464.28d2b2fe.js"><link rel="prefetch" href="/assets/js/465.474d09dd.js"><link rel="prefetch" href="/assets/js/466.3d79bf1d.js"><link rel="prefetch" href="/assets/js/467.0e38992e.js"><link rel="prefetch" href="/assets/js/468.23f8dbdb.js"><link rel="prefetch" href="/assets/js/469.424ab64e.js"><link rel="prefetch" href="/assets/js/47.fa77c18f.js"><link rel="prefetch" href="/assets/js/470.8e15adc4.js"><link rel="prefetch" href="/assets/js/471.e478b277.js"><link rel="prefetch" href="/assets/js/472.75eed247.js"><link rel="prefetch" href="/assets/js/473.676ac02f.js"><link rel="prefetch" href="/assets/js/474.ec676f10.js"><link rel="prefetch" href="/assets/js/475.0b3a7bb3.js"><link rel="prefetch" href="/assets/js/476.1dccc2bf.js"><link rel="prefetch" href="/assets/js/477.19774d6a.js"><link rel="prefetch" href="/assets/js/478.562bcdfb.js"><link rel="prefetch" href="/assets/js/479.0fdf39e1.js"><link rel="prefetch" href="/assets/js/48.55ba7067.js"><link rel="prefetch" href="/assets/js/480.32cb0959.js"><link rel="prefetch" href="/assets/js/481.39744803.js"><link rel="prefetch" href="/assets/js/482.82ff750c.js"><link rel="prefetch" href="/assets/js/483.59be5f3b.js"><link rel="prefetch" href="/assets/js/484.b47730ba.js"><link rel="prefetch" href="/assets/js/485.514e284f.js"><link rel="prefetch" href="/assets/js/486.8d407228.js"><link rel="prefetch" href="/assets/js/487.623afb9a.js"><link rel="prefetch" href="/assets/js/488.d575377d.js"><link rel="prefetch" href="/assets/js/49.369b2ef4.js"><link rel="prefetch" href="/assets/js/5.89e027e6.js"><link rel="prefetch" href="/assets/js/50.32e51808.js"><link rel="prefetch" href="/assets/js/51.48af1f55.js"><link rel="prefetch" href="/assets/js/52.0ff3366f.js"><link rel="prefetch" href="/assets/js/53.f663d530.js"><link rel="prefetch" href="/assets/js/54.57eabb55.js"><link rel="prefetch" href="/assets/js/55.00e0bdd0.js"><link rel="prefetch" href="/assets/js/56.b638bc9a.js"><link rel="prefetch" href="/assets/js/57.68420705.js"><link rel="prefetch" href="/assets/js/58.f0a325a2.js"><link rel="prefetch" href="/assets/js/59.30debc93.js"><link rel="prefetch" href="/assets/js/6.0db48d19.js"><link rel="prefetch" href="/assets/js/60.48490f44.js"><link rel="prefetch" href="/assets/js/61.26a984a9.js"><link rel="prefetch" href="/assets/js/62.f0add27d.js"><link rel="prefetch" href="/assets/js/63.07c42d31.js"><link rel="prefetch" href="/assets/js/65.c159a057.js"><link rel="prefetch" href="/assets/js/66.80e96020.js"><link rel="prefetch" href="/assets/js/67.42eabf7d.js"><link rel="prefetch" href="/assets/js/68.2a7e9954.js"><link rel="prefetch" href="/assets/js/69.4579e421.js"><link rel="prefetch" href="/assets/js/7.037ecfb1.js"><link rel="prefetch" href="/assets/js/70.4e7b95d4.js"><link rel="prefetch" href="/assets/js/71.5df75825.js"><link rel="prefetch" href="/assets/js/72.6239ec2a.js"><link rel="prefetch" href="/assets/js/73.c2458335.js"><link rel="prefetch" href="/assets/js/74.b86599e1.js"><link rel="prefetch" href="/assets/js/75.8d14cab7.js"><link rel="prefetch" href="/assets/js/76.82bf4b00.js"><link rel="prefetch" href="/assets/js/77.f5a890cc.js"><link rel="prefetch" href="/assets/js/78.f3c574f3.js"><link rel="prefetch" href="/assets/js/79.c9c56bf3.js"><link rel="prefetch" href="/assets/js/8.03d32196.js"><link rel="prefetch" href="/assets/js/80.24c4483b.js"><link rel="prefetch" href="/assets/js/81.e6653250.js"><link rel="prefetch" href="/assets/js/82.0da4ae5d.js"><link rel="prefetch" href="/assets/js/83.89a8c965.js"><link rel="prefetch" href="/assets/js/84.56206c88.js"><link rel="prefetch" href="/assets/js/85.0daf7cf7.js"><link rel="prefetch" href="/assets/js/86.0a17b684.js"><link rel="prefetch" href="/assets/js/87.f7cf9412.js"><link rel="prefetch" href="/assets/js/88.22341e3f.js"><link rel="prefetch" href="/assets/js/89.2166c8bb.js"><link rel="prefetch" href="/assets/js/9.a241a058.js"><link rel="prefetch" href="/assets/js/90.9440815d.js"><link rel="prefetch" href="/assets/js/91.5ea69e27.js"><link rel="prefetch" href="/assets/js/92.cea1c8dd.js"><link rel="prefetch" href="/assets/js/93.2e94ab93.js"><link rel="prefetch" href="/assets/js/94.1674ba0c.js"><link rel="prefetch" href="/assets/js/95.c6ba057e.js"><link rel="prefetch" href="/assets/js/96.ee719565.js"><link rel="prefetch" href="/assets/js/97.a814f163.js"><link rel="prefetch" href="/assets/js/98.748b1098.js"><link rel="prefetch" href="/assets/js/99.c6176c0d.js">
    <link rel="stylesheet" href="/assets/css/0.styles.e57fdc06.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><img src="/logo.png" alt="房飞跃的博客" class="logo"> <span class="site-name can-hide">房飞跃的博客</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="前端" class="dropdown-title"><span class="title">前端</span> <span class="arrow down"></span></button> <button type="button" aria-label="前端" class="mobile-dropdown-title"><span class="title">前端</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>
          Vue
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/books/深入浅出Vue.js/01.html" class="nav-link">
  深入浅出Vue
</a></li><li class="dropdown-subitem"><a href="/front/vue/vue/01.html" class="nav-link">
  Vue
</a></li><li class="dropdown-subitem"><a href="/front/vue/vue-router/01.html" class="nav-link">
  VueRouter
</a></li><li class="dropdown-subitem"><a href="/front/vue/Vuex/01.html" class="nav-link">
  Vuex
</a></li><li class="dropdown-subitem"><a href="/front/vue/vue3/01.html" class="nav-link">
  Vue3核心剖析
</a></li><li class="dropdown-subitem"><a href="/front/vue/Vue知识点简单梳理/01.html" class="nav-link">
  Vue知识点简单梳理
</a></li></ul></li><li class="dropdown-item"><h4>
          React
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/books/深入React技术栈/01.html" class="nav-link">
  深入React技术栈
</a></li><li class="dropdown-subitem"><a href="/front/react/React进阶实践指南/01.html" class="nav-link">
  React进阶实践指南
</a></li><li class="dropdown-subitem"><a href="/front/react/React知识点简单梳理/01.html" class="nav-link">
  React知识点简单梳理
</a></li></ul></li><li class="dropdown-item"><h4>
          混合开发
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/混合开发/01.html" class="nav-link">
  混合开发探究
</a></li></ul></li><li class="dropdown-item"><h4>
          TypeScript
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/ts/极简入门Typescript/01.html" class="nav-link">
  极简入门Typescript
</a></li></ul></li><li class="dropdown-item"><h4>
          Webpack
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/webpack/极简入门webpack/01.html" class="nav-link">
  极简入门
</a></li><li class="dropdown-subitem"><a href="/front/webpack/常见面试题/01.html" class="nav-link">
  常见面试题
</a></li></ul></li><li class="dropdown-item"><h4>
          设计模式
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/设计模式/JS设计模式核心原理和应用实践/01.html" class="nav-link">
  JS设计模式核心原理和应用实践
</a></li></ul></li><li class="dropdown-item"><h4>
          算法和数据结构
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/算法和数据结构/入门级算法/01.html" class="nav-link">
  入门级算法
</a></li><li class="dropdown-subitem"><a href="/front/算法和数据结构/常见算法/01.html" class="nav-link">
  常见算法
</a></li><li class="dropdown-subitem"><a href="/front/算法和数据结构/常见数据结构/01.html" class="nav-link">
  常见数据结构
</a></li><li class="dropdown-subitem"><a href="/front/算法和数据结构/前端算法与数据结构/01.html" class="nav-link">
  前端算法与数据结构
</a></li></ul></li><li class="dropdown-item"><h4>
          基础必备
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/base/html必备/01.html" class="nav-link">
  HTML必备
</a></li><li class="dropdown-subitem"><a href="/front/base/CSS必备/01.html" class="nav-link">
  CSS必备
</a></li><li class="dropdown-subitem"><a href="/front/base/JS基础/01.html" class="nav-link">
  JS基础
</a></li><li class="dropdown-subitem"><a href="/front/base/JS进阶/01.html" class="nav-link">
  JS进阶
</a></li><li class="dropdown-subitem"><a href="/front/base/JS练习/01.html" class="nav-link">
  JS练习
</a></li><li class="dropdown-subitem"><a href="/front/base/网络基础/01.html" class="nav-link">
  网络基础
</a></li><li class="dropdown-subitem"><a href="/books/JS高级程序设计/01.html" class="nav-link">
  JS高级程序设计
</a></li><li class="dropdown-subitem"><a href="/front/base/浏览器相关基础/01.html" class="nav-link">
  浏览器相关基础
</a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="电子" class="dropdown-title"><span class="title">电子</span> <span class="arrow down"></span></button> <button type="button" aria-label="电子" class="mobile-dropdown-title"><span class="title">电子</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>
          STM32
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/电子/STM32四轴飞行器/01.html" class="nav-link">
  STM32四轴飞行器
</a></li></ul></li><li class="dropdown-item"><h4>
          Arduino
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/电子/Arduino墙画机/01.html" class="nav-link">
  Arduino墙画机
</a></li><li class="dropdown-subitem"><a href="/电子/Arduino四轴飞行器/01.html" class="nav-link">
  Arduino四轴飞行器
</a></li><li class="dropdown-subitem"><a href="/电子/Arduino四足仿生机器人/01.html" class="nav-link">
  Arduino四足仿生机器人
</a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="关于" class="dropdown-title"><span class="title">关于</span> <span class="arrow down"></span></button> <button type="button" aria-label="关于" class="mobile-dropdown-title"><span class="title">关于</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/关于我/01.html" class="nav-link">
  关于我
</a></li><li class="dropdown-item"><!----> <a href="https://github.com/fangfeiyue" target="_blank" rel="noopener noreferrer" class="nav-link external">
  Github
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="前端" class="dropdown-title"><span class="title">前端</span> <span class="arrow down"></span></button> <button type="button" aria-label="前端" class="mobile-dropdown-title"><span class="title">前端</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>
          Vue
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/books/深入浅出Vue.js/01.html" class="nav-link">
  深入浅出Vue
</a></li><li class="dropdown-subitem"><a href="/front/vue/vue/01.html" class="nav-link">
  Vue
</a></li><li class="dropdown-subitem"><a href="/front/vue/vue-router/01.html" class="nav-link">
  VueRouter
</a></li><li class="dropdown-subitem"><a href="/front/vue/Vuex/01.html" class="nav-link">
  Vuex
</a></li><li class="dropdown-subitem"><a href="/front/vue/vue3/01.html" class="nav-link">
  Vue3核心剖析
</a></li><li class="dropdown-subitem"><a href="/front/vue/Vue知识点简单梳理/01.html" class="nav-link">
  Vue知识点简单梳理
</a></li></ul></li><li class="dropdown-item"><h4>
          React
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/books/深入React技术栈/01.html" class="nav-link">
  深入React技术栈
</a></li><li class="dropdown-subitem"><a href="/front/react/React进阶实践指南/01.html" class="nav-link">
  React进阶实践指南
</a></li><li class="dropdown-subitem"><a href="/front/react/React知识点简单梳理/01.html" class="nav-link">
  React知识点简单梳理
</a></li></ul></li><li class="dropdown-item"><h4>
          混合开发
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/混合开发/01.html" class="nav-link">
  混合开发探究
</a></li></ul></li><li class="dropdown-item"><h4>
          TypeScript
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/ts/极简入门Typescript/01.html" class="nav-link">
  极简入门Typescript
</a></li></ul></li><li class="dropdown-item"><h4>
          Webpack
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/webpack/极简入门webpack/01.html" class="nav-link">
  极简入门
</a></li><li class="dropdown-subitem"><a href="/front/webpack/常见面试题/01.html" class="nav-link">
  常见面试题
</a></li></ul></li><li class="dropdown-item"><h4>
          设计模式
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/设计模式/JS设计模式核心原理和应用实践/01.html" class="nav-link">
  JS设计模式核心原理和应用实践
</a></li></ul></li><li class="dropdown-item"><h4>
          算法和数据结构
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/算法和数据结构/入门级算法/01.html" class="nav-link">
  入门级算法
</a></li><li class="dropdown-subitem"><a href="/front/算法和数据结构/常见算法/01.html" class="nav-link">
  常见算法
</a></li><li class="dropdown-subitem"><a href="/front/算法和数据结构/常见数据结构/01.html" class="nav-link">
  常见数据结构
</a></li><li class="dropdown-subitem"><a href="/front/算法和数据结构/前端算法与数据结构/01.html" class="nav-link">
  前端算法与数据结构
</a></li></ul></li><li class="dropdown-item"><h4>
          基础必备
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/front/base/html必备/01.html" class="nav-link">
  HTML必备
</a></li><li class="dropdown-subitem"><a href="/front/base/CSS必备/01.html" class="nav-link">
  CSS必备
</a></li><li class="dropdown-subitem"><a href="/front/base/JS基础/01.html" class="nav-link">
  JS基础
</a></li><li class="dropdown-subitem"><a href="/front/base/JS进阶/01.html" class="nav-link">
  JS进阶
</a></li><li class="dropdown-subitem"><a href="/front/base/JS练习/01.html" class="nav-link">
  JS练习
</a></li><li class="dropdown-subitem"><a href="/front/base/网络基础/01.html" class="nav-link">
  网络基础
</a></li><li class="dropdown-subitem"><a href="/books/JS高级程序设计/01.html" class="nav-link">
  JS高级程序设计
</a></li><li class="dropdown-subitem"><a href="/front/base/浏览器相关基础/01.html" class="nav-link">
  浏览器相关基础
</a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="电子" class="dropdown-title"><span class="title">电子</span> <span class="arrow down"></span></button> <button type="button" aria-label="电子" class="mobile-dropdown-title"><span class="title">电子</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>
          STM32
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/电子/STM32四轴飞行器/01.html" class="nav-link">
  STM32四轴飞行器
</a></li></ul></li><li class="dropdown-item"><h4>
          Arduino
        </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/电子/Arduino墙画机/01.html" class="nav-link">
  Arduino墙画机
</a></li><li class="dropdown-subitem"><a href="/电子/Arduino四轴飞行器/01.html" class="nav-link">
  Arduino四轴飞行器
</a></li><li class="dropdown-subitem"><a href="/电子/Arduino四足仿生机器人/01.html" class="nav-link">
  Arduino四足仿生机器人
</a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="关于" class="dropdown-title"><span class="title">关于</span> <span class="arrow down"></span></button> <button type="button" aria-label="关于" class="mobile-dropdown-title"><span class="title">关于</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/关于我/01.html" class="nav-link">
  关于我
</a></li><li class="dropdown-item"><!----> <a href="https://github.com/fangfeiyue" target="_blank" rel="noopener noreferrer" class="nav-link external">
  Github
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div> <!----></nav>  <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>常见面试题</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/front/webpack/常见面试题/01.html" class="sidebar-link">与webpack类似的工具有哪些？谈谈你为什么选择使用或者放弃webpack？</a></li><li><a href="/front/webpack/常见面试题/02.html" class="sidebar-link">loader和plugin的不同</a></li><li><a href="/front/webpack/常见面试题/03.html" class="sidebar-link">如何调试webpack代码</a></li><li><a href="/front/webpack/常见面试题/04.html" class="sidebar-link">webpack的构建流程是什么？</a></li><li><a href="/front/webpack/常见面试题/05.html" class="sidebar-link">有哪些常见的loader和plugin？他们都解决什么问题？</a></li><li><a href="/front/webpack/常见面试题/06.html" class="sidebar-link">source map是什么？生产环境怎么用？</a></li><li><a href="/front/webpack/常见面试题/07.html" class="active sidebar-link">如何利用webpack来优化前端性能？</a></li><li><a href="/front/webpack/常见面试题/08.html" class="sidebar-link">webpack中hash、chunkhash、contenthash区别？</a></li><li><a href="/front/webpack/常见面试题/09.html" class="sidebar-link">如何对bundle体积进行监控和分析</a></li><li><a href="/front/webpack/常见面试题/10.html" class="sidebar-link">如何提高webpack的构建速度</a></li><li><a href="/front/webpack/常见面试题/11.html" class="sidebar-link">inline loader、pre loader、 post loader和normal loader执行的先后顺序是什么?</a></li><li><a href="/front/webpack/常见面试题/12.html" class="sidebar-link">怎样编写一个loader</a></li><li><a href="/front/webpack/常见面试题/13.html" class="sidebar-link">怎样编写一个plugin?</a></li><li><a href="/front/webpack/常见面试题/14.html" class="sidebar-link">webpack打包的原理是什么?聊一聊babel和抽象语法树吧</a></li><li><a href="/front/webpack/常见面试题/15.html" class="sidebar-link">tree-shaking</a></li><li><a href="/front/webpack/常见面试题/16.html" class="sidebar-link">webpack热更新</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h2 id="_1-安装"><a href="#_1-安装" class="header-anchor">#</a> 1. 安装</h2> <div class="language-js extra-class"><pre class="language-js"><code>cnpm i react react<span class="token operator">-</span>dom  <span class="token operator">-</span><span class="token constant">S</span>
cnpm install  webpack webpack<span class="token operator">-</span>cli webpack<span class="token operator">-</span>dev<span class="token operator">-</span>server image<span class="token operator">-</span>webpack<span class="token operator">-</span>loader mini<span class="token operator">-</span>css<span class="token operator">-</span>extract<span class="token operator">-</span>plugin purgecss<span class="token operator">-</span>webpack<span class="token operator">-</span>plugin babel<span class="token operator">-</span>loader @babel<span class="token operator">/</span>core @babel<span class="token operator">/</span>preset<span class="token operator">-</span>env @babel<span class="token operator">/</span>preset<span class="token operator">-</span>react terser<span class="token operator">-</span>webpack<span class="token operator">-</span>plugin html<span class="token operator">-</span>webpack<span class="token operator">-</span>plugin optimize<span class="token operator">-</span>css<span class="token operator">-</span>assets<span class="token operator">-</span>webpack<span class="token operator">-</span>plugin mini<span class="token operator">-</span>css<span class="token operator">-</span>extract<span class="token operator">-</span>plugin qiniu webpack<span class="token operator">-</span>bundle<span class="token operator">-</span>analyzer <span class="token operator">-</span><span class="token constant">D</span>
</code></pre></div><h2 id="_2-压缩js"><a href="#_2-压缩js" class="header-anchor">#</a> 2.压缩JS</h2> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> optimization: {
</span><span class="token prefix unchanged"> </span><span class="token line">   minimize: true,
</span><span class="token prefix unchanged"> </span><span class="token line">   minimizer: [
</span><span class="token prefix unchanged"> </span><span class="token line">     //压缩JS
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">     new TerserPlugin({})
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   ]
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span></span></code></pre></div><h2 id="_3-压缩css"><a href="#_3-压缩css" class="header-anchor">#</a> 3. 压缩CSS</h2> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> optimization: {
</span><span class="token prefix unchanged"> </span><span class="token line">   minimize: true,
</span><span class="token prefix unchanged"> </span><span class="token line">   minimizer: [
</span><span class="token prefix unchanged"> </span><span class="token line">     //压缩CSS
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      new OptimizeCSSAssetsPlugin({}),
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   ]
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span></span></code></pre></div><h2 id="_4-压缩图片"><a href="#_4-压缩图片" class="header-anchor">#</a> 4. 压缩图片</h2> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">     {
</span><span class="token prefix unchanged"> </span><span class="token line">       test: /\.(png|svg|jpg|gif|jpeg|ico)$/,
</span><span class="token prefix unchanged"> </span><span class="token line">       use: [
</span><span class="token prefix unchanged"> </span><span class="token line">         &quot;file-loader&quot;,
</span><span class="token prefix unchanged"> </span><span class="token line">         {
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">            loader: &quot;image-webpack-loader&quot;,
</span><span class="token prefix inserted">+</span><span class="token line">            options: {
</span><span class="token prefix inserted">+</span><span class="token line">              mozjpeg: {
</span><span class="token prefix inserted">+</span><span class="token line">                progressive: true,
</span><span class="token prefix inserted">+</span><span class="token line">                quality: 65,
</span><span class="token prefix inserted">+</span><span class="token line">              },
</span><span class="token prefix inserted">+</span><span class="token line">              optipng: {
</span><span class="token prefix inserted">+</span><span class="token line">                enabled: false,
</span><span class="token prefix inserted">+</span><span class="token line">              },
</span><span class="token prefix inserted">+</span><span class="token line">              pngquant: {
</span><span class="token prefix inserted">+</span><span class="token line">                quality: &quot;65-90&quot;,
</span><span class="token prefix inserted">+</span><span class="token line">                speed: 4,
</span><span class="token prefix inserted">+</span><span class="token line">              },
</span><span class="token prefix inserted">+</span><span class="token line">              gifsicle: {
</span><span class="token prefix inserted">+</span><span class="token line">                interlaced: false,
</span><span class="token prefix inserted">+</span><span class="token line">              },
</span><span class="token prefix inserted">+</span><span class="token line">              webp: {
</span><span class="token prefix inserted">+</span><span class="token line">                quality: 75,
</span><span class="token prefix inserted">+</span><span class="token line">              }
</span><span class="token prefix inserted">+</span><span class="token line">            }
</span><span class="token prefix inserted">+</span><span class="token line">          }
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">       ]
</span><span class="token prefix unchanged"> </span><span class="token line">     }
</span></span></code></pre></div><h2 id="_5-清除无用的css"><a href="#_5-清除无用的css" class="header-anchor">#</a> 5. 清除无用的CSS</h2> <ul><li>单独提取CSS并清除用不到的CSS</li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code>const path = require(&quot;path&quot;);
<span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">const MiniCssExtractPlugin = require(&quot;mini-css-extract-plugin&quot;);
</span><span class="token prefix inserted">+</span><span class="token line">const PurgecssPlugin = require(&quot;purgecss-webpack-plugin&quot;);
</span></span>module.exports = {
<span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> module: {
</span><span class="token prefix unchanged"> </span><span class="token line">   rules: [
</span><span class="token prefix unchanged"> </span><span class="token line">      {
</span><span class="token prefix unchanged"> </span><span class="token line">       test: /\.css$/,
</span><span class="token prefix unchanged"> </span><span class="token line">       include: path.resolve(__dirname, &quot;src&quot;),
</span><span class="token prefix unchanged"> </span><span class="token line">       exclude: /node_modules/,
</span><span class="token prefix unchanged"> </span><span class="token line">       use: [
</span><span class="token prefix unchanged"> </span><span class="token line">         {
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">            loader: MiniCssExtractPlugin.loader,
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">         },
</span><span class="token prefix unchanged"> </span><span class="token line">         &quot;css-loader&quot;,
</span><span class="token prefix unchanged"> </span><span class="token line">       ],
</span><span class="token prefix unchanged"> </span><span class="token line">     }
</span><span class="token prefix unchanged"> </span><span class="token line">   ]
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span><span class="token prefix unchanged"> </span><span class="token line"> plugins: [
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">    new MiniCssExtractPlugin({
</span><span class="token prefix inserted">+</span><span class="token line">      filename: &quot;[name].css&quot;,
</span><span class="token prefix inserted">+</span><span class="token line">    }),
</span><span class="token prefix inserted">+</span><span class="token line">    new PurgecssPlugin({
</span><span class="token prefix inserted">+</span><span class="token line">      paths: glob.sync(`${PATHS.src}/**/*`,  { nodir: true }),
</span><span class="token prefix inserted">+</span><span class="token line">    })
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> ]
</span><span class="token prefix unchanged"> </span><span class="token line"> devServer: {},
</span></span>};

</code></pre></div><h2 id="_6-tree-shaking"><a href="#_6-tree-shaking" class="header-anchor">#</a> 6. Tree Shaking</h2> <ul><li>一个模块可以有多个方法，只要其中某个方法使用到了，则整个文件都会被打到bundle里面去，tree shaking就是只把用到的方法打入bundle,没用到的方法会uglify阶段擦除掉</li> <li>原理是利用es6模块的特点,只能作为模块顶层语句出现,import的模块名只能是字符串常量</li> <li>webpack默认支持，在.babelrc里设置module:false即可在production mode下默认开启</li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code>module.exports = {
<span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">    mode:'production',
</span><span class="token prefix inserted">+</span><span class="token line">    devtool:false,
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">    module: {
</span><span class="token prefix unchanged"> </span><span class="token line">       rules: [
</span><span class="token prefix unchanged"> </span><span class="token line">           {
</span><span class="token prefix unchanged"> </span><span class="token line">               test: /\.js/,
</span><span class="token prefix unchanged"> </span><span class="token line">               include: path.resolve(__dirname, &quot;src&quot;),
</span><span class="token prefix unchanged"> </span><span class="token line">               use: [
</span><span class="token prefix unchanged"> </span><span class="token line">                   {
</span><span class="token prefix unchanged"> </span><span class="token line">                       loader: &quot;babel-loader&quot;,
</span><span class="token prefix unchanged"> </span><span class="token line">                       options: {
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">                            presets: [[&quot;@babel/preset-env&quot;, { &quot;modules&quot;: false }]],
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">                       },
</span><span class="token prefix unchanged"> </span><span class="token line">                   },
</span><span class="token prefix unchanged"> </span><span class="token line">               ],
</span><span class="token prefix unchanged"> </span><span class="token line">           }
</span><span class="token prefix unchanged"> </span><span class="token line">    }
</span></span>}
</code></pre></div><h2 id="_7-scope-hoisting"><a href="#_7-scope-hoisting" class="header-anchor">#</a> 7. Scope Hoisting</h2> <ul><li>Scope Hoisting 可以让 Webpack 打包出来的代码文件更小、运行的更快， 它又译作 &quot;作用域提升&quot;，是在 Webpack3 中新推出的功能。</li> <li>scope hoisting的原理是将所有的模块按照引用顺序放在一个函数作用域里，然后适当地重命名一些变量以防止命名冲突</li> <li>这个功能在mode为<code>production</code>下默认开启,开发环境要用 <code>webpack.optimize.ModuleConcatenationPlugin</code>插件</li></ul> <p>hello.js</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token string">'Hello'</span><span class="token punctuation">;</span>
</code></pre></div><p>index.js</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> str <span class="token keyword">from</span> <span class="token string">'./hello.js'</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>main.js</p> <div class="language-js: extra-class"><pre class="language-text"><code>var hello = ('hello');
console.log(hello);
</code></pre></div><h2 id="_8-代码分割"><a href="#_8-代码分割" class="header-anchor">#</a> 8. 代码分割</h2> <ul><li>对于大的Web应用来讲，将所有的代码都放在一个文件中显然是不够有效的，特别是当你的某些代码块是在某些特殊的时候才会被用到。</li> <li>webpack有一个功能就是将你的代码库分割成chunks语块，当代码运行到需要它们的时候再进行加载</li></ul> <h3 id="_8-1-入口点分割"><a href="#_8-1-入口点分割" class="header-anchor">#</a> 8.1 入口点分割</h3> <ul><li>Entry Points：入口文件设置的时候可以配置</li> <li>这种方法的问题
<ul><li>如果入口 chunks 之间包含重复的模块(lodash)，那些重复模块都会被引入到各个 bundle 中</li> <li>不够灵活，并且不能将核心应用程序逻辑进行动态拆分代码</li></ul></li></ul> <div class="language-js extra-class"><pre class="language-js"><code>entry<span class="token operator">:</span> <span class="token punctuation">{</span>
        index<span class="token operator">:</span> <span class="token string">&quot;./src/index.js&quot;</span><span class="token punctuation">,</span>
        login<span class="token operator">:</span> <span class="token string">&quot;./src/login.js&quot;</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="_8-2-动态导入和懒加载"><a href="#_8-2-动态导入和懒加载" class="header-anchor">#</a> 8.2  动态导入和懒加载</h3> <p>用户当前需要用什么功能就只加载这个功能对应的代码，也就是所谓的按需加载 在给单页应用做按需加载优化时</p> <ul><li>一般采用以下原则：
<ul><li>对网站功能进行划分，每一类一个chunk</li> <li>对于首次打开页面需要的功能直接加载，尽快展示给用户,某些依赖大量代码的功能点可以按需加载</li> <li>被分割出去的代码需要一个按需加载的时机</li></ul></li></ul> <p>hello.js</p> <div class="language-js extra-class"><pre class="language-js"><code>module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token string">&quot;hello&quot;</span><span class="token punctuation">;</span>
</code></pre></div><p>index.js</p> <div class="language-js extra-class"><pre class="language-js"><code>document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'#clickBtn'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">import</span><span class="token punctuation">(</span><span class="token string">'./hello'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">result</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">.</span>default<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>index.html</p> <div class="language-html extra-class"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>clickBtn<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>点我<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><h3 id="_8-3-preload-预先加载"><a href="#_8-3-preload-预先加载" class="header-anchor">#</a> 8.3 preload(预先加载)</h3> <ul><li>preload通常用于本页面要用到的关键资源，包括关键js、字体、css文件</li> <li>preload将会把资源得下载顺序权重提高，使得关键数据提前下载好,优化页面打开速度</li> <li>在资源上添加预先加载的注释，你指明该模块需要立即被使用</li> <li>一个资源的加载的优先级被分为五个级别,分别是
<ul><li>Highest 最高</li> <li>High 高</li> <li>Medium 中等</li> <li>Low 低</li> <li>Lowest 最低</li></ul></li> <li>异步/延迟/插入的脚本（无论在什么位置）在网络优先级中是 <code>Low</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token operator">&lt;</span>link rel<span class="token operator">=</span><span class="token string">&quot;preload&quot;</span> <span class="token keyword">as</span><span class="token operator">=</span><span class="token string">&quot;script&quot;</span> href<span class="token operator">=</span><span class="token string">&quot;utils.js&quot;</span><span class="token operator">&gt;</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span><span class="token punctuation">(</span>
  <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">./utils.js</span><span class="token template-punctuation string">`</span></span>
  <span class="token comment">/* webpackPreload: true */</span>
  <span class="token comment">/* webpackChunkName: &quot;utils&quot; */</span>
<span class="token punctuation">)</span>
</code></pre></div><h3 id="_8-4-prefetch-预先拉取"><a href="#_8-4-prefetch-预先拉取" class="header-anchor">#</a> 8.4 prefetch(预先拉取)</h3> <ul><li>prefetch 跟 preload 不同，它的作用是告诉浏览器未来可能会使用到的某个资源，浏览器就会在闲时去加载对应的资源，若能预测到用户的行为，比如懒加载，点击到其它页面等则相当于提前预加载了需要的资源</li></ul> <div class="language-html extra-class"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>link</span> <span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>prefetch<span class="token punctuation">&quot;</span></span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>utils.js<span class="token punctuation">&quot;</span></span> <span class="token attr-name">as</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>script<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>button<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">import</span><span class="token punctuation">(</span>
    <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">./utils.js</span><span class="token template-punctuation string">`</span></span>
    <span class="token comment">/* webpackPrefetch: true */</span>
    <span class="token comment">/* webpackChunkName: &quot;utils&quot; */</span>
  <span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">result</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    result<span class="token punctuation">.</span>default<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'hello'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

</code></pre></div><h3 id="_8-5-preload-vs-prefetch"><a href="#_8-5-preload-vs-prefetch" class="header-anchor">#</a> 8.5 preload vs prefetch</h3> <ul><li>preload 是告诉浏览器页面必定需要的资源，浏览器一定会加载这些资源</li> <li>而 prefetch 是告诉浏览器页面可能需要的资源，浏览器不一定会加载这些资源</li> <li>所以建议：对于当前页面很有必要的资源使用 preload,对于可能在将来的页面中使用的资源使用 prefetch</li></ul> <h3 id="_8-6-提取公共代码"><a href="#_8-6-提取公共代码" class="header-anchor">#</a> 8.6 提取公共代码</h3> <h4 id="_8-6-1-为什么需要提取公共代码"><a href="#_8-6-1-为什么需要提取公共代码" class="header-anchor">#</a> 8.6.1 为什么需要提取公共代码</h4> <ul><li>大网站有多个页面，每个页面由于采用相同技术栈和样式代码，会包含很多公共代码，如果都包含进来会有问题</li> <li>相同的资源被重复的加载，浪费用户的流量和服务器的成本；</li> <li>每个页面需要加载的资源太大，导致网页首屏加载缓慢，影响用户体验。</li> <li>如果能把公共代码抽离成单独文件进行加载能进行优化，可以减少网络传输流量，降低服务器成本</li></ul> <h4 id="_8-6-2-如何提取"><a href="#_8-6-2-如何提取" class="header-anchor">#</a> 8.6.2 如何提取</h4> <ul><li>基础类库，方便长期缓存</li> <li>页面之间的公用代码</li> <li>各个页面单独生成文件</li></ul> <h4 id="_8-6-3-splitchunks"><a href="#_8-6-3-splitchunks" class="header-anchor">#</a> 8.6.3 splitChunks</h4> <h5 id="_8-6-3-1-module-chunk-bundle"><a href="#_8-6-3-1-module-chunk-bundle" class="header-anchor">#</a> 8.6.3.1 module chunk  bundle</h5> <ul><li>module：就是js的模块化webpack支持commonJS、ES6等模块化规范，简单来说就是你通过import语句引入的代码</li> <li>chunk: chunk是webpack根据功能拆分出来的，包含三种情况
<ul><li>你的项目入口（entry）</li> <li>通过import()动态引入的代码</li> <li>通过splitChunks拆分出来的代码</li></ul></li> <li>bundle：bundle是webpack打包之后的各个文件，一般就是和chunk是一对一的关系，bundle就是对chunk进行编译压缩打包等处理之后的产出</li></ul> <h5 id="_8-6-3-2-默认配置"><a href="#_8-6-3-2-默认配置" class="header-anchor">#</a> 8.6.3.2  默认配置</h5> <p>webpack.config.js</p> <div class="language-js extra-class"><pre class="language-js"><code>  entry<span class="token operator">:</span> <span class="token punctuation">{</span>
    page1<span class="token operator">:</span> <span class="token string">&quot;./src/page1.js&quot;</span><span class="token punctuation">,</span>
    page2<span class="token operator">:</span> <span class="token string">&quot;./src/page2.js&quot;</span><span class="token punctuation">,</span>
    page3<span class="token operator">:</span> <span class="token string">&quot;./src/page3.js&quot;</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
 optimization<span class="token operator">:</span> <span class="token punctuation">{</span>
  splitChunks<span class="token operator">:</span> <span class="token punctuation">{</span>
      chunks<span class="token operator">:</span> <span class="token string">&quot;all&quot;</span><span class="token punctuation">,</span> <span class="token comment">//默认作用于异步chunk，值为all/initial/async</span>
      minSize<span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token comment">//默认值是30kb,代码块的最小尺寸</span>
      minChunks<span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token comment">//被多少模块共享,在分割之前模块的被引用次数</span>
      maxAsyncRequests<span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token comment">//限制异步模块内部的并行最大请求数的，说白了你可以理解为是每个import()它里面的最大并行请求数量</span>
      maxInitialRequests<span class="token operator">:</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token comment">//限制入口的拆分数量</span>
      name<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token comment">//打包后的名称，默认是chunk的名字通过分隔符（默认是～）分隔开，如vendor~</span>
      automaticNameDelimiter<span class="token operator">:</span> <span class="token string">&quot;~&quot;</span><span class="token punctuation">,</span> <span class="token comment">//默认webpack将会使用入口名和代码块的名称生成命名,比如 'vendors~main.js'</span>
      cacheGroups<span class="token operator">:</span> <span class="token punctuation">{</span>
        <span class="token comment">//设置缓存组用来抽取满足不同规则的chunk,下面以生成common为例</span>
        vendors<span class="token operator">:</span> <span class="token punctuation">{</span>
          chunks<span class="token operator">:</span> <span class="token string">&quot;all&quot;</span><span class="token punctuation">,</span>
          test<span class="token operator">:</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">node_modules</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">,</span> <span class="token comment">//条件</span>
          priority<span class="token operator">:</span> <span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token comment">///优先级，一个chunk很可能满足多个缓存组，会被抽取到优先级高的缓存组中,为了能够让自定义缓存组有更高的优先级(默认0),默认缓存组的priority属性为负值.</span>
        <span class="token punctuation">}</span><span class="token punctuation">,</span>
        commons<span class="token operator">:</span> <span class="token punctuation">{</span>
          chunks<span class="token operator">:</span> <span class="token string">&quot;all&quot;</span><span class="token punctuation">,</span>
          minSize<span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token comment">//最小提取字节数</span>
          minChunks<span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token comment">//最少被几个chunk引用</span>
          priority<span class="token operator">:</span> <span class="token operator">-</span><span class="token number">20</span>
        <span class="token punctuation">}</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
</code></pre></div><p>src\page1.js</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> utils1 <span class="token keyword">from</span> <span class="token string">&quot;./module1&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> utils2 <span class="token keyword">from</span> <span class="token string">&quot;./module2&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> $ <span class="token keyword">from</span> <span class="token string">&quot;jquery&quot;</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>utils1<span class="token punctuation">,</span> utils2<span class="token punctuation">,</span> $<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">import</span><span class="token punctuation">(</span><span class="token comment">/* webpackChunkName: &quot;asyncModule1&quot; */</span> <span class="token string">&quot;./asyncModule1&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>src\page2.js</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> utils1 <span class="token keyword">from</span> <span class="token string">&quot;./module1&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> utils2 <span class="token keyword">from</span> <span class="token string">&quot;./module2&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> $ <span class="token keyword">from</span> <span class="token string">&quot;jquery&quot;</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>utils1<span class="token punctuation">,</span> utils2<span class="token punctuation">,</span> $<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>src\page3.js</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> utils1 <span class="token keyword">from</span> <span class="token string">&quot;./module1&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> utils3 <span class="token keyword">from</span> <span class="token string">&quot;./module3&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> $ <span class="token keyword">from</span> <span class="token string">&quot;jquery&quot;</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>utils1<span class="token punctuation">,</span> utils3<span class="token punctuation">,</span> $<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>src\module1.js</p> <div class="language-js extra-class"><pre class="language-js"><code>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;module1&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>src\module2.js</p> <div class="language-js extra-class"><pre class="language-js"><code>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;module2&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>src\module3.js</p> <div class="language-js extra-class"><pre class="language-js"><code>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;module3&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>src\asyncModule1.js</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> _ <span class="token keyword">from</span> <span class="token string">'lodash'</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>_<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>                             Asset       Size                     Chunks             Chunk Names
             asyncModule1<span class="token punctuation">.</span>chunk<span class="token punctuation">.</span>js  <span class="token number">740</span> bytes               asyncModule1  <span class="token punctuation">[</span>emitted<span class="token punctuation">]</span>  asyncModule1
                        index<span class="token punctuation">.</span>html  <span class="token number">498</span> bytes                             <span class="token punctuation">[</span>emitted<span class="token punctuation">]</span>
                          page1<span class="token punctuation">.</span>js   <span class="token number">10.6</span> KiB                      page1  <span class="token punctuation">[</span>emitted<span class="token punctuation">]</span>  page1
              page1<span class="token operator">~</span>page2<span class="token punctuation">.</span>chunk<span class="token punctuation">.</span>js  <span class="token number">302</span> bytes                page1<span class="token operator">~</span>page2  <span class="token punctuation">[</span>emitted<span class="token punctuation">]</span>  page1<span class="token operator">~</span>page2
        page1<span class="token operator">~</span>page2<span class="token operator">~</span>page3<span class="token punctuation">.</span>chunk<span class="token punctuation">.</span>js  <span class="token number">308</span> bytes          page1<span class="token operator">~</span>page2<span class="token operator">~</span>page3  <span class="token punctuation">[</span>emitted<span class="token punctuation">]</span>  page1<span class="token operator">~</span>page2<span class="token operator">~</span>page3
                          page2<span class="token punctuation">.</span>js   <span class="token number">7.52</span> KiB                      page2  <span class="token punctuation">[</span>emitted<span class="token punctuation">]</span>  page2
                          page3<span class="token punctuation">.</span>js   <span class="token number">7.72</span> KiB                      page3  <span class="token punctuation">[</span>emitted<span class="token punctuation">]</span>  page3
     vendors<span class="token operator">~</span>asyncModule1<span class="token punctuation">.</span>chunk<span class="token punctuation">.</span>js    <span class="token number">532</span> KiB       vendors<span class="token operator">~</span>asyncModule1  <span class="token punctuation">[</span>emitted<span class="token punctuation">]</span>  vendors<span class="token operator">~</span>asyncModule1
vendors<span class="token operator">~</span>page1<span class="token operator">~</span>page2<span class="token operator">~</span>page3<span class="token punctuation">.</span>chunk<span class="token punctuation">.</span>js    <span class="token number">282</span> KiB  vendors<span class="token operator">~</span>page1<span class="token operator">~</span>page2<span class="token operator">~</span>page3  <span class="token punctuation">[</span>emitted<span class="token punctuation">]</span>  vendors<span class="token operator">~</span>page1<span class="token operator">~</span>page2<span class="token operator">~</span>page3
Entrypoint page1 <span class="token operator">=</span> vendors<span class="token operator">~</span>page1<span class="token operator">~</span>page2<span class="token operator">~</span>page3<span class="token punctuation">.</span>chunk<span class="token punctuation">.</span>js page1<span class="token operator">~</span>page2<span class="token operator">~</span>page3<span class="token punctuation">.</span>chunk<span class="token punctuation">.</span>js page1<span class="token operator">~</span>page2<span class="token punctuation">.</span>chunk<span class="token punctuation">.</span>js page1<span class="token punctuation">.</span>js
Entrypoint page2 <span class="token operator">=</span> vendors<span class="token operator">~</span>page1<span class="token operator">~</span>page2<span class="token operator">~</span>page3<span class="token punctuation">.</span>chunk<span class="token punctuation">.</span>js page1<span class="token operator">~</span>page2<span class="token operator">~</span>page3<span class="token punctuation">.</span>chunk<span class="token punctuation">.</span>js page1<span class="token operator">~</span>page2<span class="token punctuation">.</span>chunk<span class="token punctuation">.</span>js page2<span class="token punctuation">.</span>js
Entrypoint page3 <span class="token operator">=</span> vendors<span class="token operator">~</span>page1<span class="token operator">~</span>page2<span class="token operator">~</span>page3<span class="token punctuation">.</span>chunk<span class="token punctuation">.</span>js page1<span class="token operator">~</span>page2<span class="token operator">~</span>page3<span class="token punctuation">.</span>chunk<span class="token punctuation">.</span>js page3<span class="token punctuation">.</span>js
</code></pre></div><p><img src="http://img.zhufengpeixun.cn/splitChunks.jpg" alt="splitChunks"></p> <h2 id="_6-cdn"><a href="#_6-cdn" class="header-anchor">#</a> 6. CDN</h2> <ul><li>最影响用户体验的是网页首次打开时的加载等待。 导致这个问题的根本是网络传输过程耗时大，CDN的作用就是加速网络传输。</li> <li>CDN 又叫内容分发网络，通过把资源部署到世界各地，用户在访问时按照就近原则从离用户最近的服务器获取资源，从而加速资源的获取速度</li> <li>缓存配置
<ul><li>HTML文件不缓存，放在自己的服务器上，关闭自己服务器的缓存，静态资源的URL变成指向CDN服务器的地址</li> <li>静态的JavaScript、CSS、图片等文件开启CDN和缓存，并且文件名带上HASH值</li> <li>为了并行加载不阻塞，把不同的静态资源分配到不同的CDN服务器上</li></ul></li> <li>域名限制
<ul><li>同一时刻针对同一个域名的资源并行请求是有限制</li> <li>可以把这些静态资源分散到不同的 CDN 服务上去</li> <li>多个域名后会增加域名解析时间</li> <li>可以通过在 HTML HEAD 标签中 加入<link rel="dns-prefetch" href="http://img.zhufengpeixun.cn">去预解析域名，以降低域名解析带来的延迟</li></ul></li></ul> <h3 id="_6-1-webpack-config-js"><a href="#_6-1-webpack-config-js" class="header-anchor">#</a> 6.1 webpack.config.js</h3> <div class="language-diff extra-class"><pre class="language-diff"><code>const path = require(&quot;path&quot;);
const MiniCssExtractPlugin = require(&quot;mini-css-extract-plugin&quot;);
const PurgecssPlugin = require(&quot;purgecss-webpack-plugin&quot;);
const TerserPlugin = require(&quot;terser-webpack-plugin&quot;);
const OptimizeCSSAssetsPlugin = require(&quot;optimize-css-assets-webpack-plugin&quot;);
const HtmlWebpackPlugin = require(&quot;html-webpack-plugin&quot;);
const UploadPlugin = require(&quot;./plugins/UploadPlugin&quot;);
const glob = require(&quot;glob&quot;);
const PATHS = {
<span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   src: path.join(__dirname, &quot;src&quot;),
</span></span>};
module.exports = {
<span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> mode: &quot;development&quot;,
</span><span class="token prefix unchanged"> </span><span class="token line"> devtool: false,
</span><span class="token prefix unchanged"> </span><span class="token line"> context: process.cwd(),
</span><span class="token prefix unchanged"> </span><span class="token line"> entry: {
</span><span class="token prefix unchanged"> </span><span class="token line">   main: &quot;./src/index.js&quot;,
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span><span class="token prefix unchanged"> </span><span class="token line"> output: {
</span><span class="token prefix unchanged"> </span><span class="token line">   path: path.resolve(__dirname, &quot;dist&quot;),
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">    filename: &quot;[name].[hash].js&quot;,
</span><span class="token prefix inserted">+</span><span class="token line">    chunkFilename: &quot;[name].[hash].chunk.js&quot;,
</span><span class="token prefix inserted">+</span><span class="token line">    publicPath: &quot;http://img.zhufengpeixun.cn/&quot;,
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> },
</span><span class="token prefix unchanged"> </span><span class="token line"> optimization: {
</span><span class="token prefix unchanged"> </span><span class="token line">   minimize: true,
</span><span class="token prefix unchanged"> </span><span class="token line">   minimizer: [
</span><span class="token prefix unchanged"> </span><span class="token line">     //压缩JS
</span><span class="token prefix unchanged"> </span><span class="token line">     /* new TerserPlugin({
</span><span class="token prefix unchanged"> </span><span class="token line">       sourceMap: false,
</span><span class="token prefix unchanged"> </span><span class="token line">       extractComments: false,
</span><span class="token prefix unchanged"> </span><span class="token line">     }),
</span><span class="token prefix unchanged"> </span><span class="token line">     //压缩CSS
</span><span class="token prefix unchanged"> </span><span class="token line">     new OptimizeCSSAssetsPlugin({}), */
</span><span class="token prefix unchanged"> </span><span class="token line">   ],
</span><span class="token prefix unchanged"> </span><span class="token line">   //自动分割第三方模块和公共模块
</span><span class="token prefix unchanged"> </span><span class="token line">   splitChunks: {
</span><span class="token prefix unchanged"> </span><span class="token line">     chunks: &quot;all&quot;, //默认作用于异步chunk，值为all/initial/async
</span><span class="token prefix unchanged"> </span><span class="token line">     minSize: 0, //默认值是30kb,代码块的最小尺寸
</span><span class="token prefix unchanged"> </span><span class="token line">     minChunks: 1, //被多少模块共享,在分割之前模块的被引用次数
</span><span class="token prefix unchanged"> </span><span class="token line">     maxAsyncRequests: 2, //限制异步模块内部的并行最大请求数的，说白了你可以理解为是每个import()它里面的最大并行请求数量
</span><span class="token prefix unchanged"> </span><span class="token line">     maxInitialRequests: 4, //限制入口的拆分数量
</span><span class="token prefix unchanged"> </span><span class="token line">     name: true, //打包后的名称，默认是chunk的名字通过分隔符（默认是～）分隔开，如vendor~
</span><span class="token prefix unchanged"> </span><span class="token line">     automaticNameDelimiter: &quot;~&quot;, //默认webpack将会使用入口名和代码块的名称生成命名,比如 'vendors~main.js'
</span><span class="token prefix unchanged"> </span><span class="token line">     cacheGroups: {
</span><span class="token prefix unchanged"> </span><span class="token line">       //设置缓存组用来抽取满足不同规则的chunk,下面以生成common为例
</span><span class="token prefix unchanged"> </span><span class="token line">       vendors: {
</span><span class="token prefix unchanged"> </span><span class="token line">         chunks: &quot;all&quot;,
</span><span class="token prefix unchanged"> </span><span class="token line">         test: /node_modules/, //条件
</span><span class="token prefix unchanged"> </span><span class="token line">         priority: -10, ///优先级，一个chunk很可能满足多个缓存组，会被抽取到优先级高的缓存组中,为了能够让自定义缓存组有更高的优先级(默认0),默认缓存组的priority属性为负值.
</span><span class="token prefix unchanged"> </span><span class="token line">       },
</span><span class="token prefix unchanged"> </span><span class="token line">       commons: {
</span><span class="token prefix unchanged"> </span><span class="token line">         chunks: &quot;all&quot;,
</span><span class="token prefix unchanged"> </span><span class="token line">         minSize: 0, //最小提取字节数
</span><span class="token prefix unchanged"> </span><span class="token line">         minChunks: 2, //最少被几个chunk引用
</span><span class="token prefix unchanged"> </span><span class="token line">         priority: -20,
</span><span class="token prefix unchanged"> </span><span class="token line">         reuseExistingChunk: true, //如果该chunk中引用了已经被抽取的chunk，直接引用该chunk，不会重复打包代码
</span><span class="token prefix unchanged"> </span><span class="token line">       },
</span><span class="token prefix unchanged"> </span><span class="token line">     },
</span><span class="token prefix unchanged"> </span><span class="token line">   },
</span><span class="token prefix unchanged"> </span><span class="token line">   //为了长期缓存保持运行时代码块是单独的文件
</span><span class="token prefix unchanged"> </span><span class="token line">   /*  runtimeChunk: {
</span><span class="token prefix unchanged"> </span><span class="token line">     name: (entrypoint) =&gt; `runtime-${entrypoint.name}`,
</span><span class="token prefix unchanged"> </span><span class="token line">   }, */
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span><span class="token prefix unchanged"> </span><span class="token line"> module: {
</span><span class="token prefix unchanged"> </span><span class="token line">   rules: [
</span><span class="token prefix unchanged"> </span><span class="token line">     {
</span><span class="token prefix unchanged"> </span><span class="token line">       test: /\.js/,
</span><span class="token prefix unchanged"> </span><span class="token line">       include: path.resolve(__dirname, &quot;src&quot;),
</span><span class="token prefix unchanged"> </span><span class="token line">       use: [
</span><span class="token prefix unchanged"> </span><span class="token line">         {
</span><span class="token prefix unchanged"> </span><span class="token line">           loader: &quot;babel-loader&quot;,
</span><span class="token prefix unchanged"> </span><span class="token line">           options: {
</span><span class="token prefix unchanged"> </span><span class="token line">             presets: [
</span><span class="token prefix unchanged"> </span><span class="token line">               [&quot;@babel/preset-env&quot;, { modules: false }],
</span><span class="token prefix unchanged"> </span><span class="token line">               &quot;@babel/preset-react&quot;,
</span><span class="token prefix unchanged"> </span><span class="token line">             ],
</span><span class="token prefix unchanged"> </span><span class="token line">           },
</span><span class="token prefix unchanged"> </span><span class="token line">         },
</span><span class="token prefix unchanged"> </span><span class="token line">       ],
</span><span class="token prefix unchanged"> </span><span class="token line">     },
</span><span class="token prefix unchanged"> </span><span class="token line">     {
</span><span class="token prefix unchanged"> </span><span class="token line">       test: /\.css$/,
</span><span class="token prefix unchanged"> </span><span class="token line">       include: path.resolve(__dirname, &quot;src&quot;),
</span><span class="token prefix unchanged"> </span><span class="token line">       exclude: /node_modules/,
</span><span class="token prefix unchanged"> </span><span class="token line">       use: [
</span><span class="token prefix unchanged"> </span><span class="token line">         {
</span><span class="token prefix unchanged"> </span><span class="token line">           loader: MiniCssExtractPlugin.loader,
</span><span class="token prefix unchanged"> </span><span class="token line">         },
</span><span class="token prefix unchanged"> </span><span class="token line">         &quot;css-loader&quot;,
</span><span class="token prefix unchanged"> </span><span class="token line">       ],
</span><span class="token prefix unchanged"> </span><span class="token line">     },
</span><span class="token prefix unchanged"> </span><span class="token line">     {
</span><span class="token prefix unchanged"> </span><span class="token line">       test: /\.(png|svg|jpg|gif|jpeg|ico)$/,
</span><span class="token prefix unchanged"> </span><span class="token line">       use: [
</span><span class="token prefix unchanged"> </span><span class="token line">         &quot;file-loader&quot;,
</span><span class="token prefix unchanged"> </span><span class="token line">         {
</span><span class="token prefix unchanged"> </span><span class="token line">           loader: &quot;image-webpack-loader&quot;,
</span><span class="token prefix unchanged"> </span><span class="token line">           options: {
</span><span class="token prefix unchanged"> </span><span class="token line">             mozjpeg: {
</span><span class="token prefix unchanged"> </span><span class="token line">               progressive: true,
</span><span class="token prefix unchanged"> </span><span class="token line">               quality: 65,
</span><span class="token prefix unchanged"> </span><span class="token line">             },
</span><span class="token prefix unchanged"> </span><span class="token line">             optipng: {
</span><span class="token prefix unchanged"> </span><span class="token line">               enabled: false,
</span><span class="token prefix unchanged"> </span><span class="token line">             },
</span><span class="token prefix unchanged"> </span><span class="token line">             pngquant: {
</span><span class="token prefix unchanged"> </span><span class="token line">               quality: &quot;65-90&quot;,
</span><span class="token prefix unchanged"> </span><span class="token line">               speed: 4,
</span><span class="token prefix unchanged"> </span><span class="token line">             },
</span><span class="token prefix unchanged"> </span><span class="token line">             gifsicle: {
</span><span class="token prefix unchanged"> </span><span class="token line">               interlaced: false,
</span><span class="token prefix unchanged"> </span><span class="token line">             },
</span><span class="token prefix unchanged"> </span><span class="token line">             webp: {
</span><span class="token prefix unchanged"> </span><span class="token line">               quality: 75,
</span><span class="token prefix unchanged"> </span><span class="token line">             },
</span><span class="token prefix unchanged"> </span><span class="token line">           },
</span><span class="token prefix unchanged"> </span><span class="token line">         },
</span><span class="token prefix unchanged"> </span><span class="token line">       ],
</span><span class="token prefix unchanged"> </span><span class="token line">     },
</span><span class="token prefix unchanged"> </span><span class="token line">   ],
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span><span class="token prefix unchanged"> </span><span class="token line"> plugins: [
</span><span class="token prefix unchanged"> </span><span class="token line">   new HtmlWebpackPlugin({
</span><span class="token prefix unchanged"> </span><span class="token line">     inject: true,
</span><span class="token prefix unchanged"> </span><span class="token line">     template: &quot;./src/index.html&quot;,
</span><span class="token prefix unchanged"> </span><span class="token line">   }),
</span><span class="token prefix unchanged"> </span><span class="token line">   new MiniCssExtractPlugin({
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      filename: &quot;[name].[hash].css&quot;,
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   }),
</span><span class="token prefix unchanged"> </span><span class="token line">   new PurgecssPlugin({
</span><span class="token prefix unchanged"> </span><span class="token line">     paths: glob.sync(`${PATHS.src}/**/*`, { nodir: true }),
</span><span class="token prefix unchanged"> </span><span class="token line">   }),
</span><span class="token prefix unchanged"> </span><span class="token line">   new UploadPlugin({}),
</span><span class="token prefix unchanged"> </span><span class="token line"> ],
</span><span class="token prefix unchanged"> </span><span class="token line"> devServer: {},
</span></span>};
</code></pre></div><h3 id="_6-2-uploadplugin-js"><a href="#_6-2-uploadplugin-js" class="header-anchor">#</a> 6.2 UploadPlugin.js</h3> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> qiniu <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&quot;qiniu&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> path <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&quot;path&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//https://developer.qiniu.com/kodo/sdk/1289/nodejs</span>
<span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&quot;dotenv&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">config</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> defaultAccessKey <span class="token operator">=</span> process<span class="token punctuation">.</span>env<span class="token punctuation">.</span>accessKey<span class="token punctuation">;</span>
<span class="token keyword">const</span> defaultSecretKey <span class="token operator">=</span> process<span class="token punctuation">.</span>env<span class="token punctuation">.</span>secretKey<span class="token punctuation">;</span>
<span class="token keyword">class</span> <span class="token class-name">UploadPlugin</span> <span class="token punctuation">{</span>
  <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">options</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>options <span class="token operator">=</span> options <span class="token operator">||</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token function">apply</span><span class="token punctuation">(</span><span class="token parameter">compiler</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">//在webpack把产出的文件写入硬盘后</span>
    compiler<span class="token punctuation">.</span>hooks<span class="token punctuation">.</span>afterEmit<span class="token punctuation">.</span><span class="token function">tap</span><span class="token punctuation">(</span><span class="token string">&quot;UploadPlugin&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">compilation</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token comment">//把本次编译产出的文件上传到七牛上</span>
      <span class="token keyword">let</span> assets <span class="token operator">=</span> compilation<span class="token punctuation">.</span>assets<span class="token punctuation">;</span>
      <span class="token comment">//html不需要强缓存的,是需要放在自己的服务器上,不需要缓存,</span>
      <span class="token keyword">let</span> promises <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>assets<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token operator">=&gt;</span><span class="token operator">!</span>item<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span><span class="token string">'.html'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">upload</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      Promise<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span>promises<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">err<span class="token punctuation">,</span> data</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">,</span> data<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token function">upload</span><span class="token punctuation">(</span><span class="token parameter">filename</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token keyword">let</span> <span class="token punctuation">{</span>
        bucket <span class="token operator">=</span> <span class="token string">&quot;cnpmjs&quot;</span><span class="token punctuation">,</span>
        accessKey <span class="token operator">=</span> defaultAccessKey<span class="token punctuation">,</span>
        secretKey <span class="token operator">=</span> defaultSecretKey<span class="token punctuation">,</span>
      <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>options<span class="token punctuation">;</span>
      <span class="token keyword">let</span> mac <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">qiniu<span class="token punctuation">.</span>auth<span class="token punctuation">.</span>digest<span class="token punctuation">.</span>Mac</span><span class="token punctuation">(</span>accessKey<span class="token punctuation">,</span> secretKey<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">let</span> options <span class="token operator">=</span> <span class="token punctuation">{</span>
        scope<span class="token operator">:</span> bucket<span class="token punctuation">,</span>
      <span class="token punctuation">}</span><span class="token punctuation">;</span>

      <span class="token keyword">let</span> putPolicy <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">qiniu<span class="token punctuation">.</span>rs<span class="token punctuation">.</span>PutPolicy</span><span class="token punctuation">(</span>options<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">let</span> uploadToken <span class="token operator">=</span> putPolicy<span class="token punctuation">.</span><span class="token function">uploadToken</span><span class="token punctuation">(</span>mac<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">let</span> config <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">qiniu<span class="token punctuation">.</span>conf<span class="token punctuation">.</span>Config</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

      <span class="token keyword">let</span> localFile <span class="token operator">=</span> path<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>__dirname<span class="token punctuation">,</span> <span class="token string">&quot;../dist&quot;</span><span class="token punctuation">,</span> filename<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">let</span> formUploader <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">qiniu<span class="token punctuation">.</span>form_up<span class="token punctuation">.</span>FormUploader</span><span class="token punctuation">(</span>config<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">let</span> putExtra <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">qiniu<span class="token punctuation">.</span>form_up<span class="token punctuation">.</span>PutExtra</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      formUploader<span class="token punctuation">.</span><span class="token function">putFile</span><span class="token punctuation">(</span>
        uploadToken<span class="token punctuation">,</span>
        filename<span class="token punctuation">,</span>
        localFile<span class="token punctuation">,</span>
        putExtra<span class="token punctuation">,</span>
        <span class="token punctuation">(</span><span class="token parameter">err<span class="token punctuation">,</span> body<span class="token punctuation">,</span> info</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
          err <span class="token operator">?</span> <span class="token function">reject</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">resolve</span><span class="token punctuation">(</span>body<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
      <span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

module<span class="token punctuation">.</span>exports <span class="token operator">=</span> UploadPlugin<span class="token punctuation">;</span>
</code></pre></div></div> <footer class="page-edit"><!----> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev">
      ←
      <a href="/front/webpack/常见面试题/06.html" class="prev">
        source map是什么？生产环境怎么用？
      </a></span> <span class="next"><a href="/front/webpack/常见面试题/08.html">
        webpack中hash、chunkhash、contenthash区别？
      </a>
      →
    </span></p></div> </main></div><div class="global-ui"><!----><!----></div></div>
    <script src="/assets/js/app.8c5a7a92.js" defer></script><script src="/assets/js/2.8e30e130.js" defer></script><script src="/assets/js/325.f54af6ec.js" defer></script><script src="/assets/js/64.0323ed89.js" defer></script>
  </body>
</html>
